#
# A "cache" module for the Linux Counter
#
# A cache will cache one particular key -> value binding, not entire
# objects. It has a configurable timeout value - if an element is retrieved
# after this timeout, or is not in cache, the function will be invoked
# to get it.
#
package Counter::Cache;

sub new {

    my $self = {};
    my $class = shift;
    my $proc = shift;
    my $timeout = shift;

    bless($self, $class);


    $timeout = 60 if !defined($timeout);

    $$self{timeout} = $timeout;
    $$self{proc} = $proc;
    $$self{values} = {};
    $$self{times} = {};
    $$self{hits} = 0;
    $$self{misses} = 0;
    return $self;

}

sub get {
    my $self = shift;
    my $key = shift;
    my $now = time();
    my $val;
    if (!defined($$self{times}{$key})
	|| $$self{times}{$key} <= $now - $$self{timeout}) {
	$val = &{$$self{proc}}($key);
	$$self{values}{$key} = $val;
	$$self{times}{$key} = $now;
	++ $$self{misses};
    } else {
	$val = $$self{values}{$key};
	++ $$self{hits};
    }
    return $val;
}

sub timeout {
    my $self = shift;
    my $arg = shift;
    my $timeout = $$self{timeout};
    $$self{timeout} = $arg if defined($arg);
    return $timeout;
}

# Report statistics. Debug function - print on stdout!
sub statistics {
    my $self = shift;
    print "Number of entries: ", scalar(keys(%{$$self{values}})), "\n";
    print "Hits: ", $$self{hits}, "\n";
    print "Misses: ", $$self{misses}, "\n";
}

1;
